package charts.series.bars ;
import flash.filters.DropShadowFilter;
import flash.geom.Matrix;

class PlasticFlat extends Base
{
	
	public function new ( index: Int, style:Dynamic, group: Float ) {
		super(index, style, style.color, style.tip, style.alpha, group);
		
		var dropShadow:DropShadowFilter = new flash.filters.DropShadowFilter();
		dropShadow.blurX = 5;
		dropShadow.blurY = 5;
		dropShadow.distance = 3;
		dropShadow.angle = 45;
		dropShadow.quality = 2;
		dropShadow.alpha = 0.4;
		// apply shadow filter
		this.filters = [dropShadow];
	}
	
	public override function resize ( sc:ScreenCoordsBase ):Void {
		this.graphics.clear();
		var h:Dynamic = this.resize_helper( cast(sc,ScreenCoords));
		
		this.bg( h.width, h.height, h.upside_down );
		this.glass( h.width, h.height, h.upside_down );
	}
	
	function bg ( w: Float, h: Float, upside_down:Bool ):Void {

		var rad: Float = w/3;
		if ( rad > ( w / 2 ) )
			rad = w / 2;
		
		this.graphics.lineStyle(0, 0, 0);// this.outline_color, 100);
		
		var allcolors:Array<Int> = getColors(this.color);
		var lowlight: Float = allcolors[2];
		var highlight: Int = allcolors[0];
		var bgcolors:Array<Float> = [allcolors[1], allcolors[2], allcolors[2]];
		var bgalphas:Array<Float> = [1, 1, 1];
		var bgratios:Array<Int> = [0, 115, 255];
		//var bgcolors:Array<Float> = [allcolors[1], allcolors[2]];
		//var bgalphas:Array<Float> = [1, 1];
		//var bgratios:Array<Int> = [0, 255];
		var bgmatrix:Matrix = new Matrix();
		var xRadius: Float;
		var yRadius: Float;
		var x: Float;
		var y: Float;
		var bevel: Float = 0.02 * w;
		var div: Float = 3;
		
		bgmatrix.createGradientBox(w, h, (180 / 180) * Math.PI );
		this.graphics.beginGradientFill('linear' /*GradientType.Linear*/, bgcolors, bgalphas, bgratios, bgmatrix, 'pad'/*SpreadMethod.PAD*/ );
		
		if ( h > 0 || h < 0)
		{ /* height is not zero */
			
			/* draw outline darker rounded rectangle */
			this.graphics.beginFill(0x000000, 1);         
			this.graphics.drawRoundRect(0, 0, w, h, w/div, w/div);
			
			/* draw inner highlight rounded rectangle */
			this.graphics.beginFill(highlight, 1);
			this.graphics.drawRoundRect(0 + bevel, 0 + bevel, w - 2 * bevel, h - 2 * bevel, w/div - 2*bevel, w/div - 2 * bevel);
			
			/* draw inner gradient rounded rectangle */
			bevel = bevel * 3;
			this.graphics.beginGradientFill('linear' /*GradientType.Linear*/, bgcolors, bgalphas, bgratios, bgmatrix, 'pad'/*SpreadMethod.PAD*/ );
			this.graphics.drawRoundRect(0 + bevel, 0 + bevel, w - 2 * bevel, h - 2 * bevel, w/div - 2*bevel, w/div - 2 * bevel);
			
		}
		else
		{	
			/* draw outline darker rounded rectangle */
			this.graphics.beginFill(0x000000, 1);         
			this.graphics.drawRoundRect(0, 0 - 2*bevel, w, h + 4*bevel, w/div, w/div);
			
			/* draw inner highlight rounded rectangle */
			this.graphics.beginFill(highlight, 1);
			this.graphics.drawRoundRect(0 + bevel, 0 - 2*bevel + bevel, w - 2 * bevel, h + 4*bevel - 2 * bevel, w/div - 2*bevel, w/div - 2 * bevel);
			
			/* draw inner gradient rounded rectangle */
			bevel = bevel * 3;
			this.graphics.beginGradientFill('linear' /*GradientType.Linear*/, bgcolors, bgalphas, bgratios, bgmatrix, 'pad'/*SpreadMethod.PAD*/ );
			this.graphics.drawRoundRect(0 + bevel, 0 - 2*bevel + bevel, w - 2 * bevel, h + 4*bevel - 2 * bevel, w/div - 2*bevel, w/div - 2 * bevel);
			
		}		
		this.graphics.endFill();
	}
	
	function glass ( w: Float, h: Float, upside_down:Bool ): Void {
	
	/* if this section is commented out, the white shine overlay will not be drawn */
	
	this.graphics.lineStyle(0, 0, 0);
	var allcolors:Array<Int> = getColors(this.color);
	var lowlight: Float = allcolors[2];
	var highlight: Int = allcolors[0];
	var bgcolors:Array<Float> = [allcolors[1], allcolors[2], allcolors[2]];
	var bgalphas:Array<Float> = [1, 1, 1];
	var bgratios:Array<Int> = [0, 115, 255];
	var bgmatrix:Matrix = new Matrix();
	/*var colors:Array<Float> = [0xFFFFFF, 0xFFFFFF];
	var alphas:Array<Float> = [0, 0.75];
	var ratios:Array<Int> = [127,255];   */
	var colors:Array<Float> = [0xFFFFFF, 0xFFFFFF, 0xFFFFFF];
	var alphas:Array<Float> = [0, 0.05, 0.75];
	var ratios:Array<Int> = [0, 123, 255];         
	var xRadius: Float;
	var yRadius: Float;
	var x: Float;
	var y: Float;
	var matrix:Matrix = new Matrix();
	var bevel: Float = 0.02 * w;
	var div: Float = 3;
	
	bgmatrix.createGradientBox(w, h, (180 / 180) * Math.PI );
	matrix.createGradientBox(width, height, (180 / 180) * Math.PI );
	this.graphics.beginGradientFill('linear' /*GradientType.Linear*/, colors, alphas, ratios, matrix, 'pad'/*SpreadMethod.PAD*/ );
	var rad: Float = w / 3;
	
	if ( h > 0 && !upside_down )
	{ /* draw bar upwards */
	
		/* draw shine rounded rectangle */      
		this.graphics.drawRoundRect(0 + bevel, 0 + bevel, w - 2 * bevel, h - 2 * bevel, w/div - 2*bevel, w/div - 2 * bevel);
		
		/* draw outline darker rectangle */
		this.graphics.beginFill(0x000000, 1);         
		this.graphics.drawRect(0, h - h / 2, w, h/2);
		
		/* draw inner highlight rectangle */
		this.graphics.beginFill(highlight, 1);
		this.graphics.drawRect(0 + bevel, h - h / 2, w - 2 * bevel, h /2 - bevel);
		
		/* draw inner gradient rectangle */
		bevel = bevel * 3;
		this.graphics.beginGradientFill('linear' /*GradientType.Linear*/, bgcolors, bgalphas, bgratios, bgmatrix, 'pad'/*SpreadMethod.PAD*/ );
		this.graphics.drawRect(0 + bevel, h - h / 2, w - 2 * bevel, h / 2 - bevel);
		
		/* draw shine rounded rectangle */      
		bevel = bevel / 3;
		this.graphics.beginGradientFill('linear' /*GradientType.Linear*/, colors, alphas, ratios, matrix, 'pad'/*SpreadMethod.PAD*/ );
		this.graphics.drawRect(0 + bevel, h - h / 2, w - 2 * bevel, h / 2 - bevel);
		
	}
	else if ( h > 0 )
	{/* draw bar downwards */
	
		/* draw shine rounded rectangle */      
		this.graphics.drawRoundRect(0 + bevel, 0 + bevel, w - 2 * bevel, h - 2 * bevel, w/div - 2*bevel, w/div - 2 * bevel);
		
		/* draw outline darker rectangle */
		this.graphics.beginFill(0x000000, 1);         
		this.graphics.drawRect(0, 0, w, h/2);
		
		/* draw inner highlight rectangle */
		this.graphics.beginFill(highlight, 1);
		this.graphics.drawRect(0 + bevel, 0 + bevel, w - 2 * bevel, h /2 - bevel);
		
		/* draw inner gradient rectangle */
		bevel = bevel * 3;
		this.graphics.beginGradientFill('linear' /*GradientType.Linear*/, bgcolors, bgalphas, bgratios, bgmatrix, 'pad'/*SpreadMethod.PAD*/ );
		this.graphics.drawRect(0 + bevel, 0 + bevel, w - 2 * bevel, h / 2 - bevel);
		
		/* draw shine rounded rectangle */      
		bevel = bevel / 3;
		this.graphics.beginGradientFill('linear' /*GradientType.Linear*/, colors, alphas, ratios, matrix, 'pad'/*SpreadMethod.PAD*/ );
		this.graphics.drawRect(0 + bevel, 0 + bevel, w - 2 * bevel, h / 2 - bevel);
		
	}
	else
	{
		
		/* draw shine rounded rectangle */      
		this.graphics.drawRoundRect(0 + bevel, 0 - 2*bevel + bevel, w - 2 * bevel, h + 4*bevel - 2 * bevel, w/div - 2*bevel, w/div - 2 * bevel);
		
	}
		this.graphics.endFill();
	
	}
	
	/* function newto process colors */
	/* returns a base color, a lowlight color, and a highlight color for the gradients based on the color passed in */
	public static function getColors ( col: Int):Array<Int> {
		var rgb: Int = col; /* decimal value for color */
		var red: Int = (rgb & 16711680) >> 16; /* extacts the red channel */
		var green: Int = (rgb & 65280) >> 8; /* extacts the green channel */
		var blue: Int = rgb & 255; /* extacts the blue channel */
		var shift: Float = 0.15; /* shift factor */
		var loshift: Float = 1.75; /* lowlight shift factor */
		var basecolor: Int = col; /* base color to be returned */
		var lowlight: Int = col; /* lowlight color to be returned */
		var highlight: Int = col; /* highlight color to be returned */
		var bgred: Int = (rgb & 16711680) >> 16; /* red channel for highlight */
		var bggreen: Int = (rgb & 65280) >> 8; /* green channel for highlight */
		var bgblue: Int = rgb & 255; /* blue channel for highlight */
		var lored: Int = (rgb & 16711680) >> 16; /* red channel for lowlight */
		var logreen: Int = (rgb & 65280) >> 8; /* green channel for lowlight */
		var loblue: Int = rgb & 255; /* blue channel for lowlight */
		var hired: Int = (rgb & 16711680) >> 16; /* red channel for highlight */
		var higreen: Int = (rgb & 65280) >> 8; /* green channel for highlight */
		var hiblue: Int = rgb & 255; /* blue channel for highlight */
		
		/* set base color components based on ability to shift lighter and darker */
		var red_shift : Int = Std.int(red * shift);
		var blue_shift : Int = Std.int(blue * shift);
		var green_shift : Int = Std.int(green * shift);

		if (red + red_shift < 255 && red - loshift * red_shift > 0)
		{ /* red can be shifted both lighter and darker */
			bgred = red;
		}
		else
		{ /* red can be shifter either lighter or darker */
			if (red + red_shift < 255)
			{ /* red can be shifter lighter */
				bgred = red + Std.int(Std.float(red) / shift);
			}
			else
			{ /* red can be shifted darker */
				bgred = red - Std.int(loshift * Std.float(red_shift));
			}
		}
		
		if (blue + blue_shift < 255 && blue - loshift * blue_shift > 0)
		{ /* blue can be shifted both lighter and darker */
			bgblue = blue;
		}
		else
		{ /* blue can be shifter either lighter or darker */
			if (blue + blue_shift < 255)
			{ /* blue can be shifter lighter */
				bgblue = blue + blue_shift;
			}
			else
			{ /* blue can be shifted darker */
				bgblue = blue - Std.int(loshift * Std.float(blue_shift));
			}
		}
		
		if (green + green_shift < 255 && green - loshift * green_shift > 0)
		{ /* green can be shifted both lighter and darker */
			bggreen = green;
		}
		else
		{ /* green can be shifted either lighter or darker */
			if (green + green_shift < 255)
			{ /* green can be shifter lighter */
				bggreen = green + green_shift;
			}
			else
			{ /* green can be shifted darker */
				bggreen = green - Std.int(loshift * Std.float(green_shift));
			}
		}
		
		/* set highlight and lowlight components based on base colors */   
		hired = bgred + red_shift;
		lored = bgred - Std.int(loshift * Std.float(red_shift));
		hiblue = bgblue + blue_shift;
		loblue = bgblue - Std.int(loshift * Std.float(blue_shift));
		higreen = bggreen + green_shift;
		logreen = bggreen - Std.int(loshift * Std.float(green_shift));
		
		/* reinlineruct base and highlight */
		basecolor = bgred << 16 | bggreen << 8 | bgblue;
		highlight = hired << 16 | higreen << 8 | hiblue;
		lowlight = lored << 16 | logreen << 8 | loblue;
			
		/* return base, lowlight, and highlight */
		return [highlight, basecolor, lowlight];
	}
	
	/* ellipse cos helper function new*/
	public static function magicTrigFunctionX (pointRatio: Float): Float{
		return Math.cos(pointRatio*2*Math.PI);
	}
	
	/* ellipse sin helper function new*/
	public static function magicTrigFunctionY (pointRatio: Float): Float{
		return Math.sin(pointRatio*2*Math.PI);
	}
	
	/* ellipse function new*/
	/* draws an ellipse from passed center coordinates, x and y radii, and number of sides */
	public function ellipse (centerX: Float, centerY: Float, xRadius: Float, yRadius: Float, sides: Int): Void {
	
	/* move to first point on ellipse */
	this.graphics.moveTo(centerX + xRadius,  centerY);
	
	/* loop through sides and draw curves */
	for ( i in 0...(sides+1) ){
		var pointRatio: Float = i/sides;
		var xSteps: Float = magicTrigFunctionX(pointRatio);
		var ySteps: Float = magicTrigFunctionY(pointRatio);
		var pointX: Float = centerX + xSteps * xRadius;
		var pointY: Float = centerY + ySteps * yRadius;
		this.graphics.lineTo(pointX, pointY);
	}
	
	}
}
